<template>
  <div class="amap-box">
    <el-amap-search-box
      ref="search"
      class="search-box"
      :search-option="searchOption"
      :on-search-result="onSearchResult"
      :default="address"
    ></el-amap-search-box>
    <el-row :gutter="20" type="flex" style="margin-bottom: 20px">
      <el-col :span="12">
        经度:
        <el-input v-model="center[0]" style="width: 150px" disabled />
      </el-col>
      <el-col :span="12">
        纬度:
        <el-input v-model="center[1]" style="width: 150px" disabled />
      </el-col>
    </el-row>
    <el-button
      v-if="isFullScreen"
      class="isFullScreen"
      @click="isFullScreen = false"
      type="danger"
      icon="el-icon-close"
      circle
    ></el-button>
    <el-amap
      ref="map"
      vid="amapDemo"
      :center="center"
      :amap-manager="amapManager"
      :zoom="zoom"
      :events="events"
      :plugin="plugin"
      :class="['amap-demo', isFullScreen ? 'fixed' : '']"
    >
      <el-amap-circle
        v-if="circle.center"
        ref="circle"
        :center="circle.center"
        :radius="circle.radius"
        :fill-opacity="circle.fillOpacity"
        :fill-color="circle.fillColor"
      />
      <div>
        <div v-for="(item, index) in lines" :key="index">
          <el-amap-polyline
            :path="item"
            strokeWeight="1"
            strokeStyle="dashed"
            strokeColor="#CC0000"
          ></el-amap-polyline>
          <el-amap-text
            :text="
              index <= 1 ? 'A' + ((index % 2) + 1) : 'B' + ((index % 2) + 1)
            "
            :position="textPoint[index]"
          ></el-amap-text>
        </div>
      </div>
      <el-amap-marker
        v-if="marker.position"
        :position="marker.position"
        :events="marker.events"
        :visible="marker.visible"
        :draggable="marker.draggable"
      ></el-amap-marker>
      <div v-if="!curArea">
        <div v-for="item in newPoints" :key="item.id">
          <el-amap-marker
            :visible="true"
            :position="item.position"
            :icon="item.icon"
            :label="item.label"
          ></el-amap-marker>
        </div>
      </div>
      <div v-if="curArea">
        <div v-for="item in newPoints" :key="item.id">
          <el-amap-marker
            v-if="curArea == item.area"
            :visible="true"
            :position="item.position"
            :icon="item.icon"
            :label="item.label"
          ></el-amap-marker>
        </div>
      </div>
    </el-amap>
    <el-row type="flex" style="margin-top: 20px" v-if="!isDistPoint">
      <el-button @click="curArea = ''" type="danger" plain
        >全部（{{ newPoints.length }}）</el-button
      >
      <el-button
        v-if="areaPoints.A1"
        @click.native="curArea = 'A1'"
        type="primary"
        plain
        >A1（{{ areaPoints.A1.length }}）</el-button
      >
      <el-button
        v-if="areaPoints.A2"
        @click.native="curArea = 'A2'"
        type="success"
        plain
        >A2（{{ areaPoints.A2.length }}）</el-button
      >
      <el-button
        v-if="areaPoints.B1"
        @click.native="curArea = 'B1'"
        type="info"
        plain
        >B1（{{ areaPoints.B1.length }}）</el-button
      >
      <el-button
        v-if="areaPoints.B2"
        @click.native="curArea = 'B2'"
        type="warning"
        plain
        >B2（{{ areaPoints.B2.length }}）</el-button
      >
      <el-button @click.native="isFullScreen = true" type="warning" plain
        >全屏</el-button
      >
      <el-button @click.native="exportData" type="warning" plain
        >导出</el-button
      >
    </el-row>
  </div>
</template>

<script>
import Vue from "vue";
import VueAMap from "vue-amap";

Vue.use(VueAMap);
VueAMap.initAMapApiLoader({
  // 高德的key
  key: "c84c4729c04d3be3e055a47169fe294c",
  // 插件集合
  plugin: [
    "AMap.Autocomplete",
    "AMap.PlaceSearch",
    "AMap.Scale",
    "AMap.OverView",
    "AMap.ToolBar",
    "AMap.MapType",
    "AMap.PolyEditor",
    "AMap.CircleEditor",
    "AMap.Geolocation",
  ],
  v: "1.4.4",
});
let amapManager = new VueAMap.AMapManager();
export default {
  props: {
    searchOption: {
      type: Object,
      default() {
        return {};
      },
    },
    isShop: {
      type: Boolean,
      default: false,
    },
    isDistPoint: {
      type: Boolean,
      default: false,
    },
    address: {
      type: String,
      default: "",
    },
    scope: {
      type: Number,
      default: 1,
    },
    shopInfo: {
      type: Object,
      default() {
        return {};
      },
    },
    points: {
      type: Array,
      default() {
        return [];
      },
    },
    lng: {
      type: [String, Number],
      default: "",
    },
    lat: {
      type: [String, Number],
      default: "",
    },
  },
  data() {
    return {
      isFullScreen: false,
      amapManager,
      zoom: 17,
      events: {
        init: (o) => {
          this.init(this.lng, this.lat);
        },
        moveend: () => {},
        zoomchange: () => {},
        click: (e) => {},
      },
      plugin: [
        {
          pName: "ToolBar",
          defaultType: 0,
          events: {
            init(o) {
              console.log(o);
            },
          },
        },
      ],
      marker: {},
      circle: {},
      center: [this.lng, this.lat],
      lines: [],
      textPoint: [],
      curArea: "",
    };
  },
  watch: {
    address(val) {
      this.$nextTick(() => {
        this.$refs.search.keyword = val;
      });
    },
    scope() {
      console.log(this.lng, this.lat, this.scope);
      if (this.lng && this.lat && this.scope) {
        this.init(this.lng, this.lat);
      }
    },
    lng() {
      console.log(this.lng, this.lat, this.scope);
      if (this.lng && this.lat && this.scope) {
        this.init(this.lng, this.lat);
      }
    },
    lat() {
      console.log(this.lng, this.lat, this.scope);
      if (this.lng && this.lat && this.scope) {
        this.init(this.lng, this.lat);
      }
    },
    dis(val) {
      this.$emit("distArea", {
        dis: (val / 1000).toFixed(3),
        area: this.area(val, {
          lng: this.center[0],
          lat: this.center[1],
        }),
      });
    },
  },
  computed: {
    dis() {
      return this.distance(this.shopInfo.lng, this.shopInfo.lat);
    },
    newPoints() {
      return this.points.map((item) => {
        let distance = this.distance(item.lng, item.lat);
        let area = this.area(distance, { lng: item.lng, lat: item.lat });
        let icon = "";
        if (area == "A1") {
          icon = require("./icon-marker/A1-32.svg");
        } else if (area == "A2") {
          icon = require("./icon-marker/A2-32.svg");
        } else if (area == "B1") {
          icon = require("./icon-marker/B1-32.svg");
        } else if (area == "B2") {
          icon = require("./icon-marker/B2-32.svg");
        }
        return {
          distance: distance,
          area: area,
          position: [item.lng, item.lat],
          name: item.pointName,
          icon: icon,
          phone: item.pointPhone,
          shopId: item.shopId,
          address: item.address,
          id: item.id,
          label: {
            content: area + "_" + item.pointName,
            offset: [0, -15],
          },
        };
      });
    },
    areaPoints() {
      let points = [...this.newPoints];
      let areaPoints = {};
      points.forEach((item) => {
        if (!areaPoints[item.area]) {
          areaPoints[item.area] = [];
        }
        areaPoints[item.area].push(item);
      });
      return areaPoints;
    },
  },
  methods: {
    exportData() {
      this.$emit("exportData", this.areaPoints);
    },
    distance(lng, lat) {
      // 自提点在到仓库中心点的距离
      if (lng && lat) {
        return AMap.GeometryUtil.distance([lng, lat], this.center || [0, 0]);
      } else {
        return 0;
      }
    },
    area(val, lnglat) {
      // 计算在仓库的哪个区域范围
      let distArea = "";
      let center = this.isDistPoint
        ? [this.shopInfo.lng, this.shopInfo.lat]
        : this.center;
      if (val >= 0 && val <= (this.shopInfo.distScope || this.scope) * 1000) {
        if (center[0] - lnglat.lng >= 0) {
          if (center[1] - lnglat.lat > 0) {
            distArea = "B1";
          } else {
            distArea = "A1";
          }
        } else {
          if (center[1] - lnglat.lat > 0) {
            distArea = "B2";
          } else {
            distArea = "A2";
          }
        }
      } else {
        distArea = "您不在仓库范围内";
      }
      return distArea;
    },
    init(lng, lat) {
      this.center = [lng, lat];
      if (this.isShop) {
        this.setCircle(lng, lat, this.scope);
        this.getLines(lng, lat, this.scope);
        this.getTextPoints(lng, lat, this.scope);
        this.setMarker(lng, lat);
      }
      if (this.isDistPoint) {
        this.setCircle(
          this.shopInfo.lng,
          this.shopInfo.lat,
          this.shopInfo.distScope
        );
        this.getLines(
          this.shopInfo.lng,
          this.shopInfo.lat,
          this.shopInfo.distScope
        );
        this.getTextPoints(
          this.shopInfo.lng,
          this.shopInfo.lat,
          this.shopInfo.distScope
        );
        this.setMarker(lng, lat);
      }

      this.$emit("update:lng", lng);
      this.$emit("update:lat", lat);
      this.$nextTick(() => {
        this.$refs.map.$$getInstance() &&
          this.$refs.map.$$getInstance().setFitView();
      });
    },
    setMarker(lng, lat) {
      this.marker = {
        position: [lng, lat],
        events: {
          click: () => {
            // alert('click marker');
          },
          dragend: (e) => {
            console.log("---event---: dragend");
            this.markers[0].position = [e.lnglat.lng, e.lnglat.lat];
          },
        },
        visible: true,
        draggable: false,
      };
    },
    // 设置圆
    setCircle(lng, lat, scope) {
      this.circle = {
        center: [lng, lat],
        radius: parseFloat(scope) * 1000,
        borderWeight: 2,
        strokeWeight: 4,
        strokeOpacity: 0.1,
        fillOpacity: 0.2,
        strokeStyle: "dashed",
        strokeDasharray: [10, 10],
        // 线样式还支持 'dashed'
        fillColor: "#1791fc",
      };
    },
    // 设置半径
    setRadius(scope) {
      this.circle.radius = scope * 1000; //米算法
    },
    // 搜索结果
    onSearchResult(pois) {
      if (pois.length > 0) {
        this.init(pois[0].location.lng + "", pois[0].location.lat + "");
        this.$emit("update:address", this.$refs.search.keyword);
      }
    },
    // 划线
    getLines(lng, lat, scope) {
      let lines = [];
      lines.push([[lng, lat], this.getNewLatLng(lng, lat, 0, scope * 1000)]);
      lines.push([[lng, lat], this.getNewLatLng(lng, lat, 90, scope * 1000)]);
      lines.push([[lng, lat], this.getNewLatLng(lng, lat, 180, scope * 1000)]);
      lines.push([[lng, lat], this.getNewLatLng(lng, lat, 270, scope * 1000)]);
      this.lines = lines;
    },
    // 区域名称
    getTextPoints(lng, lat, scope) {
      let textPoint = [];
      textPoint.push(this.getNewLatLng(lng, lat, 315, (scope / 2) * 1000));
      textPoint.push(this.getNewLatLng(lng, lat, 45, (scope / 2) * 1000));
      textPoint.push(this.getNewLatLng(lng, lat, 225, (scope / 2) * 1000));
      textPoint.push(this.getNewLatLng(lng, lat, 135, (scope / 2) * 1000));
      this.textPoint = textPoint;
    },
    getGeolocation() {
      let self = this;
      this.plugin.push({
        pName: "Geolocation",
        events: {
          init(o) {
            // o 是高德地图定位插件实例
            o.getCurrentPosition((status, result) => {
              if (result && result.position) {
                let start = 0;

                if (
                  result.formattedAddress.indexOf(
                    result.addressComponent.province
                  ) >= 0
                ) {
                  start += result.addressComponent.province.length;
                }
                if (
                  result.formattedAddress.indexOf(
                    result.addressComponent.city
                  ) >= 0
                ) {
                  start += result.addressComponent.city.length;
                }
                if (
                  result.formattedAddress.indexOf(
                    result.addressComponent.district
                  ) >= 0
                ) {
                  start += result.addressComponent.district.length;
                }
                if (
                  result.formattedAddress.indexOf(
                    result.addressComponent.township
                  ) >= 0
                ) {
                  start += result.addressComponent.township.length;
                }
                if (
                  result.formattedAddress.indexOf(
                    result.addressComponent.street
                  ) >= 0
                ) {
                  start += result.addressComponent.street.length;
                }
                if (
                  result.formattedAddress.indexOf(
                    result.addressComponent.streetNumber
                  ) >= 0
                ) {
                  start += result.addressComponent.streetNumber.length;
                }

                self.$refs.search.keyword = result.formattedAddress.substr(
                  start,
                  result.formattedAddress.length
                );
                self.$emit(
                  "update:address",
                  result.formattedAddress.substr(
                    start,
                    result.formattedAddress.length
                  )
                );
                self.init(result.position.lng, result.position.lat);
              }
            });
          },
        },
      });
    },
    getNewLatLng(lng, lat, brng, dist) {
      //大地坐标系资料WGS-84 长半径a=6378137 短半径b=6356752.3142 扁率f=1/298.2572236
      var a = 6378137;
      var b = 6356752.3142;
      var f = 1 / 298.257223563;

      var lon1 = lng * 1;
      var lat1 = lat * 1;
      var s = dist;
      var alpha1 = brng * (Math.PI / 180); //mapNumberUtil.rad(brng);
      var sinAlpha1 = Math.sin(alpha1);
      var cosAlpha1 = Math.cos(alpha1);

      //var tanU1 = (1 - f) * Math.tan(mapNumberUtil.rad(lat1));
      var tanU1 = (1 - f) * Math.tan(lat1 * (Math.PI / 180));
      var cosU1 = 1 / Math.sqrt(1 + tanU1 * tanU1),
        sinU1 = tanU1 * cosU1;
      var sigma1 = Math.atan2(tanU1, cosAlpha1);
      var sinAlpha = cosU1 * sinAlpha1;
      var cosSqAlpha = 1 - sinAlpha * sinAlpha;
      var uSq = (cosSqAlpha * (a * a - b * b)) / (b * b);
      var A =
        1 + (uSq / 16384) * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
      var B = (uSq / 1024) * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));

      var sigma = s / (b * A),
        sigmaP = 2 * Math.PI;
      while (Math.abs(sigma - sigmaP) > 1e-12) {
        var cos2SigmaM = Math.cos(2 * sigma1 + sigma);
        var sinSigma = Math.sin(sigma);
        var cosSigma = Math.cos(sigma);
        var deltaSigma =
          B *
          sinSigma *
          (cos2SigmaM +
            (B / 4) *
              (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
                (B / 6) *
                  cos2SigmaM *
                  (-3 + 4 * sinSigma * sinSigma) *
                  (-3 + 4 * cos2SigmaM * cos2SigmaM)));
        sigmaP = sigma;
        sigma = s / (b * A) + deltaSigma;
      }

      var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
      var lat2 = Math.atan2(
        sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
        (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp)
      );
      var lambda = Math.atan2(
        sinSigma * sinAlpha1,
        cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1
      );
      var C = (f / 16) * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
      var L =
        lambda -
        (1 - C) *
          f *
          sinAlpha *
          (sigma +
            C *
              sinSigma *
              (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));

      var revAz = Math.atan2(sinAlpha, -tmp); // final bearing

      var lngLatObj = {
        lng: lon1 + L * (180 / Math.PI),
        lat: lat2 * (180 / Math.PI),
      };
      // return lngLatObj;
      return [lngLatObj.lng, lngLatObj.lat];
    },
  },
};
</script>

<style scoped>
.amap-demo {
  height: 500px;
  width: 100%;
}
.amap-demo.fixed {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 9999;
}
.isFullScreen {
  position: fixed;
  top: 15px;
  right: 15px;
  z-index: 10000;
}

.search-box {
  border: 1px solid #c0c4cc;
  height: 36px;
  line-height: 36px;
  margin: 0 0 15px;
}
</style>
<style>
.search-tips {
  width: 100%;
}

.search-tips ul li {
  height: 30px !important;
  line-height: 35px !important;
  font-size: 12px;
}

.amap-toolbar {
  z-index: 8 !important;
}
.amap-marker-label {
  border: none;
  box-shadow: 0 0 5px #999;
  border-radius: 5px;
}
</style>
